package MeteoCal.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @authors Guttadoro, Iommazzo, Saullo
 */
@Entity
@Table(name = "event")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Event.findAll", query = "SELECT e FROM Event e"),
    @NamedQuery(name = "Event.findByIdEvent", query = "SELECT e FROM Event e WHERE e.idEvent = :idEvent"),
    @NamedQuery(name = "Event.findByName", query = "SELECT e FROM Event e WHERE e.name = :name"),
    @NamedQuery(name = "Event.findByAddress", query = "SELECT e FROM Event e WHERE e.address = :address"),
    @NamedQuery(name = Event.findByCity, query = "SELECT e FROM Event e WHERE e.city = :city"),
    @NamedQuery(name = Event.findByCityAndDateBegin, query = "SELECT e FROM Event e WHERE e.city = :city and e.dateBegin = :dateBegin"),
    @NamedQuery(name = "Event.findByDateBegin", query = "SELECT e FROM Event e WHERE e.dateBegin = :dateBegin"),
    @NamedQuery(name = "Event.findByDateEnd", query = "SELECT e FROM Event e WHERE e.dateEnd = :dateEnd"),
    @NamedQuery(name = "Event.findByHourBegin", query = "SELECT e FROM Event e WHERE e.hourBegin = :hourBegin"),
    @NamedQuery(name = "Event.findByHourEnd", query = "SELECT e FROM Event e WHERE e.hourEnd = :hourEnd"),
    @NamedQuery(name = "Event.findByDescription", query = "SELECT e FROM Event e WHERE e.description = :description"),
    @NamedQuery(name = "Event.findByOutdoor", query = "SELECT e FROM Event e WHERE e.outdoor = :outdoor"),
    @NamedQuery(name = "Event.findByPublic1", query = "SELECT e FROM Event e WHERE e.public1 = :public1"),
    @NamedQuery(name = "Event.findByIdCreator", query = "SELECT e FROM Event e WHERE e.idCreator = :idCreator")})
public class Event implements Serializable {
    
    public static final String findAll = "Event.findAll";
    public static final String findByCity = "Event.findByCity";
    public static final String findByCityAndDateBegin = "findByCityAndDateBegin";

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Basic(optional = false)
    @Column(name = "idEvent")
    private Integer idEvent;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "Name")
    private String name;
    @Size(max = 45)
    @Column(name = "Address")
    private String address;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "City")
    private String city;
    @Basic(optional = false)
    @NotNull
    @Column(name = "DateBegin")
    @Temporal(TemporalType.DATE)
    private Date dateBegin;
    @Basic(optional = false)
    @NotNull
    @Column(name = "DateEnd")
    @Temporal(TemporalType.DATE)
    private Date dateEnd;
    @Basic(optional = false)
    @NotNull
    @Column(name = "HourBegin")
    @Temporal(TemporalType.TIME)
    private Date hourBegin;
    @Basic(optional = false)
    @NotNull
    @Column(name = "HourEnd")
    @Temporal(TemporalType.TIME)
    private Date hourEnd;
    @Size(max = 300)
    @Column(name = "Description")
    private String description;
    @Basic(optional = false)
    @NotNull
    @Column(name = "Outdoor")
    private boolean outdoor;
    @Basic(optional = false)
    @NotNull
    @Column(name = "Public")
    private boolean public1;
    @JoinTable(name = "forecastevent", joinColumns = {
        @JoinColumn(name = "idEvent", referencedColumnName = "idEvent")}, inverseJoinColumns = {
        @JoinColumn(name = "idWeatherForecast", referencedColumnName = "idWeatherForecast")})
    @ManyToMany
    private Collection<Weatherforecast> weatherforecastCollection;
    @JoinTable(name = "eventinschedule", joinColumns = {
        @JoinColumn(name = "idEvent", referencedColumnName = "idEvent")}, inverseJoinColumns = {
        @JoinColumn(name = "idSchedule", referencedColumnName = "idSchedule")})
    @ManyToMany(fetch=FetchType.EAGER,cascade=CascadeType.PERSIST)
    private Collection<Schedule> scheduleCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idEvent")
    private Collection<Notification> notificationCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "event")
    private Collection<Warningevent> warningeventCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "event")
    private Collection<Invitation> invitationCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "event")
    private Collection<Commentwritten> commentwrittenCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idEvent")
    private Collection<Comment> commentCollection;
    @JoinColumn(name = "idCreator", referencedColumnName = "Email")
    @ManyToOne(optional = false)
    private User idCreator;

    public Collection<Invitation> getInvitationCollection() {
        return invitationCollection;
    }

    public void setInvitationCollection(Collection<Invitation> invitationCollection) {
        this.invitationCollection = invitationCollection;
    }

    public Event() {
    }

    public Event(Integer idEvent) {
        this.idEvent = idEvent;
    }
    public Event(String name, String address, String city, String description, Date dateBegin, Date dateEnd, Date hourBegin, Date hourEnd, Boolean public1,Boolean outdoor) {
        this.idEvent = idEvent;
        this.name = name;
        this.city = city;
        this.address = address;
        this.description = description;
        this.dateBegin = dateBegin;
        this.dateEnd = dateEnd;
        this.hourBegin = hourBegin;
        this.hourEnd = hourEnd;
        this.outdoor = outdoor;
        this.public1 = public1;
    }
    
    public Event(Event event) {
        this.idEvent = event.getIdEvent();
        this.name = event.getName();
        this.city = event.getCity();
        this.address = event.getAddress();
        this.description = event.getDescription();
        this.dateBegin = event.getDateBegin();
        this.dateEnd = event.getDateEnd();
        this.hourBegin = event.getHourBegin();
        this.hourEnd = event.getHourEnd();
        this.outdoor = event.getOutdoor();
        this.public1 = event.getPublic1();
    }
    
    public Event(String name, String city, String address, String description, Date dateBegin, Date dateEnd,Boolean public1,Boolean outdoor) {
        this.name = name;
        this.city = city;
        this.dateBegin = dateBegin;
        this.dateEnd = dateEnd;
        this.description=description;
        this.address=address;
        this.public1=public1;
        this.outdoor=outdoor;
    }

    public Integer getIdEvent() {
        return idEvent;
    }

    public void setIdEvent(Integer idEvent) {
        this.idEvent = idEvent;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Date getDateBegin() {
        return dateBegin;
    }

    public void setDateBegin(Date dateBegin) {
        this.dateBegin = dateBegin;
    }

    public Date getDateEnd() {
        return dateEnd;
    }

    public void setDateEnd(Date dateEnd) {
        this.dateEnd = dateEnd;
    }

    public Date getHourBegin() {
        return hourBegin;
    }

    public void setHourBegin(Date hourBegin) {
        this.hourBegin = hourBegin;
    }

    public Date getHourEnd() {
        return hourEnd;
    }

    public void setHourEnd(Date hourEnd) {
        this.hourEnd = hourEnd;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean getOutdoor() {
        return outdoor;
    }

    public void setOutdoor(boolean outdoor) {
        this.outdoor = outdoor;
    }

    public boolean getPublic1() {
        return public1;
    }

    public void setPublic1(boolean public1) {
        this.public1 = public1;
    }

    @XmlTransient
    public Collection<Weatherforecast> getWeatherforecastCollection() {
        return weatherforecastCollection;
    }

    public void setWeatherforecastCollection(Collection<Weatherforecast> weatherforecastCollection) {
        this.weatherforecastCollection = weatherforecastCollection;
    }

    @XmlTransient
    public Collection<Schedule> getScheduleCollection() {
        return scheduleCollection;
    }

    public void setScheduleCollection(Collection<Schedule> scheduleCollection) {
        this.scheduleCollection = scheduleCollection;
    }

    @XmlTransient
    public Collection<Notification> getNotificationCollection() {
        return notificationCollection;
    }

    public void setNotificationCollection(Collection<Notification> notificationCollection) {
        this.notificationCollection = notificationCollection;
    }

    @XmlTransient
    public Collection<Warningevent> getWarningeventCollection() {
        return warningeventCollection;
    }

    public void setWarningeventCollection(Collection<Warningevent> warningeventCollection) {
        this.warningeventCollection = warningeventCollection;
    }

    @XmlTransient
    public Collection<Commentwritten> getCommentwrittenCollection() {
        return commentwrittenCollection;
    }

    public void setCommentwrittenCollection(Collection<Commentwritten> commentwrittenCollection) {
        this.commentwrittenCollection = commentwrittenCollection;
    }

    @XmlTransient
    public Collection<Comment> getCommentCollection() {
        return commentCollection;
    }

    public void setCommentCollection(Collection<Comment> commentCollection) {
        this.commentCollection = commentCollection;
    }

    public User getIdCreator() {
        return idCreator;
    }

    public void setIdCreator(User idCreator) {
        this.idCreator = idCreator;
    }
  
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (idEvent != null ? idEvent.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Event)) {
            return false;
        }
        Event other = (Event) object;
        if ((this.idEvent == null && other.idEvent != null) || (this.idEvent != null && !this.idEvent.equals(other.idEvent))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "MeteoCal.entity.Event[ idEvent=" + idEvent + " ]";
    }
    
    public Event setHoursInDate(){
        Event ev = this;
        ev.dateBegin.setHours(ev.hourBegin.getHours());
        ev.dateBegin.setMinutes(ev.hourBegin.getMinutes());
        ev.dateEnd.setHours(ev.hourEnd.getHours());
        ev.dateEnd.setMinutes(ev.hourEnd.getMinutes());
        return ev;
    }
    
    public List<String> getUsers() {
        
       List<String> l = new ArrayList<>();
       
       for (Invitation i: invitationCollection)
            l.add(i.getUser().getEmail());
        
        return l;
          
    }
    
}
